namespace Patterns4Net.PatternEnforcer.Core
{
    using Patterns4Net.Attributes;
    using System.Diagnostics.Contracts;
    using Patterns4Net.Attributes.DesignPatterns;

    /// <summary>
    /// Represents a single checker error with a message and number of it's occurrences.
    /// </summary>
    [Immutable]
    public class CheckerError
    {
        public static readonly CheckerError[] EmptyArray = new CheckerError[0];

        public CheckerError(string message)
        {
            Contract.Requires(message != null);
            Contract.Ensures(this.Message == message);
            Contract.Ensures(this.Occurences == 1);
            this.Message = message;
            this.Occurences = 1;
        }

        public CheckerError(string message, int occurences)
        {
            Contract.Requires(message != null);
            Contract.Requires(occurences > 0);
            Contract.Ensures(this.Message == message);
            Contract.Ensures(this.Occurences == occurences);
            this.Message = message;
            this.Occurences = occurences;
        }

        public int Occurences { get; private set; }

        public string Message { get; private set; }

        public override bool Equals(object obj)
        {
            if (obj == null || GetType() != obj.GetType())
            {
                return false;
            }

            return this.Message.Equals(((CheckerError)obj).Message);
        }

        public override int GetHashCode()
        {
            return this.Message.GetHashCode();
        }

        public override string ToString()
        {
            return this.Message;
        }

        [ContractInvariantMethod]
        private void ObjectInvariant()
        {
            Contract.Invariant(this.Message != null);
            Contract.Invariant(this.Occurences > 0);
        }
    }
}
